﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace System.ComponentModel.DataAnnotations
{
    /* 数据模型验证，再原验证的基础上增加以下验证
     * 
     * - 常用基础验证
     * Required(AllowEmptyStrings): 必须输入字段，AllowEmptyStrings=true，可以运行空字符串，但是不能是“空”
     * MaxLength(length) : 字段长度限制，小于等于
     * MinLength(length) : 字段长度限制，大于等于
     * Email : 电子邮件格式
     * Phone ：电话格式
     * 
     * - 新增以下验证
     * IdCard: 身份证号码
     * RequiredIF(param) : 字段param若不为空，则当前字段也不能为空
     * Enum(string[]) : 枚举验证，只能是枚举的几种输入
     */

    /// <summary>
    /// Validation IdCard
    /// </summary>
    public class IdCardAttribute : ValidationAttribute
    {
        public override string FormatErrorMessage(string name)
        {
            return $"{name} is not an idCard No";
        }

        public override bool IsValid(object value)
        {
            // 空的话不验证
            if (value == null) return true;
            var input = value.ToString().ToUpper();
            if (string.IsNullOrEmpty(input)) return true;

            var regex = "(\\d{15})|(\\d{18})|((\\d{17})X)";
            if (Regex.IsMatch(input, regex))
            {
                var dateStr = "";
                if (input.Length == 15)
                    dateStr = "19" + input.Substring(6, 6);
                else
                    dateStr = input.Substring(6, 8);

                if (DateTime.TryParseExact(dateStr, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.None, out DateTime date))
                {
                    if (date < DateTime.Now && date.AddYears(120) > DateTime.Now)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }

    /// <summary>
    /// Validation NotNull While Param is Not Null
    /// </summary>
    public class RequiredIFAttribute : ValidationAttribute
    {
        public string Param { get; set; }
        public object Value { get; set; }
        /// <summary>
        /// 其他字段满足条件时，当前字段不得为空
        /// </summary>
        /// <param name="param">比较的其他字段</param>
        /// <param name="value">null: 若指定字段不为空 value:若指定字段为指定值</param>
        public RequiredIFAttribute(string param, object value = null)
        {
            Param = param;
            Value = value;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var pValue = ParamValue(validationContext.ObjectInstance);

            if (pValue == null || string.IsNullOrEmpty(pValue.ToString()))
            {
                return ValidationResult.Success;
            }

            if (Value != null && !Value.Equals(pValue))
            {
                return ValidationResult.Success;
            }

            if (value == null || string.IsNullOrEmpty(value.ToString()))
            {
                var msg = Value == null ? "is not null" : $" is equal {Value}";
                return new ValidationResult($"while {Param} {msg}，{validationContext.MemberName} is required!");
            }

            return ValidationResult.Success;
        }

        private object ParamValue(object ObjectInstance)
        {
            var ps = ObjectInstance.GetType().GetProperty(this.Param);
            if (ps == null)
                return null;
            return ps.GetValue(ObjectInstance);
        }
    }

    /// <summary>
    /// Enum Validation
    /// </summary>
    public class EnumValueAttribute : ValidationAttribute
    {
        public object[] Values { get; set; }

        public EnumValueAttribute(params object[] values)
        {
            this.Values = values;
        }

        public override string FormatErrorMessage(string name)
        {
            return "{name} 只能是: " + string.Join(",", Values);
        }

        public override bool IsValid(object value)
        {
            return Values.Contains(value);
        }
    }
}
